﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using AutoTestEntry.Utility;
using AutoTestEntry.Data;

namespace AutoTestEntry.SpecificUtility
{
    class TestRunner
    {
        private String CHECKOUT_TYPE = "Checkout";
        private String BUILD_CASE_TYPE = "BuildCase";
        private String SRART_NUNIT_TYPE = "StartNUnit";

		private bool runBuild = true;
        private ShellExecuter shellExecuter;
        private TestEnvConfig testEnvConfig;

        private bool useSandBox = false;
        private string testAccount = "";

        #region Init
        public TestRunner()
        {
            shellExecuter = new ShellExecuter();
            shellExecuter.ShellPrintEvent += ShellPrintEventHandler;
			shellExecuter.ShellErrorEvent += ShellErrorEventHandler;
            shellExecuter.ExecuteFinishedEvent += ExecuterFinishedEventHander;

            testEnvConfig = new TestEnvConfig();
        }
        #endregion

		#region Self Defined Events
        public class NewInfoEventArgs : EventArgs
        {
            public readonly String Info;
            public NewInfoEventArgs(String info)
            {
                Info = info;
            }
        }

        public delegate void NewInfoEventHandler(Object sender, NewInfoEventArgs e);
        public event NewInfoEventHandler NewInfoEvent;

		public delegate void ErrorSVNPasswdEventHandler(Object sender, EventArgs e);
		public event ErrorSVNPasswdEventHandler ErrorSVNPasswdEvent;
        #endregion

		#region  shell execute event handler
		private void ShellPrintEventHandler(Object sender, ShellExecuter.ShellPrintEventArgs e)
		{
			NewInfoEvent(this, new NewInfoEventArgs(e.Data + Environment.NewLine));
		}

		private void ShellErrorEventHandler(Object sender, ShellExecuter.ShellErrorEventArgs e)
		{
			//TODO check if svn passwd correct
			if (e.Data.Contains("认证领域") || e.Data.Contains("Authentication realm"))
			{
				runBuild = false;
				shellExecuter.Kill();
				ErrorSVNPasswdEvent(this, new EventArgs());
			}
			else if (e.Data.Contains("服务器证书时出错") || e.Data.Contains("Error validating"))
			{
				shellExecuter.WriteCommand("p");
			}

			NewInfoEvent(this, new NewInfoEventArgs(e.Data + Environment.NewLine));
		}

		private void ExecuterFinishedEventHander(Object sender, ShellExecuter.ExecuteFinishedEventArgs e)
		{
			if (e.Type.Equals(CHECKOUT_TYPE) && runBuild)
			{
				BuildTestCase();
			}
			else if (e.Type.Equals(BUILD_CASE_TYPE))
			{
				StartNUnit();
			}
			else if (e.Type.Equals(SRART_NUNIT_TYPE))
			{

			}
		}
		#endregion

        #region Real Work
        public bool AutoRun(bool chechoutCode, bool useSandBox, string testAccount)
        {
            if (chechoutCode)
            {
                this.useSandBox = useSandBox;
                this.testAccount = testAccount;

				runBuild = true;
                CheckOutNewCode();
            }
            else if (this.useSandBox != useSandBox || this.testAccount != testAccount)
            {
                this.useSandBox = useSandBox;
                this.testAccount = testAccount;

                BuildTestCase();
            }
            else
            {
                StartNUnit();
            }
			return true;
        }


        private void CheckOutNewCode()
        {
            NewInfoEvent(this, new NewInfoEventArgs("从SVN下载最新代码..." + Environment.NewLine));
            shellExecuter.Run(GlobalInfo.LocalSvnPath,
                              "co " + GlobalInfo.SvnServerAddress + " " + GlobalInfo.LocalDestPath + 
							  " --username " + GlobalInfo.SvnUserName + " --password " + GlobalInfo.SvnPassword,
                              CHECKOUT_TYPE); 
        }

        private void BuildTestCase()
        {
            NewInfoEvent(this, new NewInfoEventArgs("编译代码" + Environment.NewLine));

            testEnvConfig.SetTestEnvironment(useSandBox, testAccount);

            shellExecuter.Run(GlobalInfo.LocalNetPath,
                              GlobalInfo.LocalDestPath + "\\EditorTest.sln /t:Clean;Rebuild /p:Configuration=Release",
                              BUILD_CASE_TYPE);
        }

        private void StartNUnit()
        {
            NewInfoEvent(this, new NewInfoEventArgs("启动NUnit" + Environment.NewLine));
            shellExecuter.Run(GlobalInfo.LocalNUnitPath,
                              GlobalInfo.LocalDestPath + "\\Editor.TestCase\\bin\\Release\\Editor.TestCase.exe",
                              SRART_NUNIT_TYPE);
        }
		#endregion
    }
}
